# filepath: d:\CompanyProject\Gitee\DBCompareX\backend\app\schemas\task_data_sync\setting.py
from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
from bson import ObjectId

class PyObjectId(ObjectId):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        if not ObjectId.is_valid(v):
            raise ValueError("无效的ObjectId")
        return ObjectId(v)

    @classmethod
    def __modify_schema__(cls, field_schema):
        field_schema.update(type="string")

# 数据同步任务配置详情基础模型
class TaskDataSyncSettingDetailBase(BaseModel):
    column_name: str = Field(..., description="列名")
    comment: Optional[str] = Field(None, description="备注")

# 数据同步目源关系基础模型
class TaskDataSyncTsMappingBase(BaseModel):
    db_info_setting_id: str = Field(..., description="数据库源配置ID")
    target_column_name: str = Field(..., description="目标数据列名")
    source_table_name: str = Field(..., description="源表名")
    source_column_name: str = Field(..., description="源表列名")
    condition: Optional[str] = Field(None, description="条件")
    priority: int = Field(..., description="优先级")
    target_query_column: Optional[str] = Field(None, description="目标表查询列名")
    source_query_column: Optional[str] = Field(None, description="源表查询列名")

# 数据同步任务配置基础模型
class TaskDataSyncSettingBase(BaseModel):
    task_name: str = Field(..., description="任务名称")
    db_info_setting_id: str = Field(..., description="数据库源配置ID")
    table_name: str = Field(..., description="表名")
    query_condition: str = Field(..., description="数据获取条件")
    cron_expression: str = Field(..., description="Cron表达式")
    status: int = Field(..., description="启用状态 (0 禁用，1启用)")
    data_limit: Optional[int] = Field(None, description="获取数据量限制")

# 创建数据同步任务的请求模型
class TaskDataSyncSettingCreate(TaskDataSyncSettingBase):
    details: List[TaskDataSyncSettingDetailBase] = Field(..., description="数据同步任务配置详情")
    ts_mapping: List[TaskDataSyncTsMappingBase] = Field(..., description="数据同步目源关系")

# 更新数据同步任务的请求模型
class TaskDataSyncSettingUpdate(BaseModel):
    id: str = Field(..., description="主键ID")
    task_name: Optional[str] = Field(None, description="任务名称")
    db_info_setting_id: Optional[str] = Field(None, description="数据库源配置ID")
    table_name: Optional[str] = Field(None, description="表名")
    query_condition: Optional[str] = Field(None, description="数据获取条件")
    cron_expression: Optional[str] = Field(None, description="Cron表达式")
    status: Optional[int] = Field(None, description="启用状态 (0 禁用，1启用)")
    data_limit: Optional[int] = Field(None, description="获取数据量限制")
    details: Optional[List[TaskDataSyncSettingDetailBase]] = Field(None, description="数据同步任务配置详情")
    ts_mapping: Optional[List[TaskDataSyncTsMappingBase]] = Field(None, description="数据同步目源关系")

# 执行数据同步任务的请求模型
class TaskDataSyncSettingExecute(BaseModel):
    id: str = Field(..., description="主键ID")

# 更新任务状态的请求模型
class TaskDataSyncSettingUpdateStatus(BaseModel):
    id: str = Field(..., description="主键ID")
    status: int = Field(..., description="启用状态 (0 禁用，1 启用)")

# 存储在数据库中的数据同步任务配置模型
class TaskDataSyncSettingInDB(TaskDataSyncSettingBase):
    id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
    created_at: datetime = Field(default_factory=datetime.now)
    created_by: str = Field(default="system")
    updated_at: Optional[datetime] = None
    updated_by: Optional[str] = None

    class Config:
        allow_population_by_field_name = True
        arbitrary_types_allowed = True
        json_encoders = {
            ObjectId: str,
            datetime: lambda dt: dt.isoformat()
        }

# 存储在数据库中的数据同步任务配置详情模型
class TaskDataSyncSettingDetailInDB(TaskDataSyncSettingDetailBase):
    id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
    task_data_sync_setting_id: str = Field(..., description="数据同步任务配置ID")

    class Config:
        allow_population_by_field_name = True
        arbitrary_types_allowed = True
        json_encoders = {
            ObjectId: str
        }

# 存储在数据库中的数据同步目源关系模型
class TaskDataSyncTsMappingInDB(TaskDataSyncTsMappingBase):
    id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
    task_data_sync_setting_id: str = Field(..., description="数据同步任务配置ID")
    created_at: datetime = Field(default_factory=datetime.now)
    created_by: str = Field(default="system")
    updated_at: Optional[datetime] = None
    updated_by: Optional[str] = None

    class Config:
        allow_population_by_field_name = True
        arbitrary_types_allowed = True
        json_encoders = {
            ObjectId: str,
            datetime: lambda dt: dt.isoformat()
        }

# 任务数据同步配置响应模型
class TaskDataSyncSettingResponse(BaseModel):
    id: str
    task_name: str
    db_info_setting_id: str
    table_name: str
    query_condition: str
    cron_expression: str
    status: int
    details: List[TaskDataSyncSettingDetailInDB]
    ts_mapping: List[TaskDataSyncTsMappingInDB]
    created_at: datetime
    created_by: str
    updated_at: Optional[datetime] = None
    updated_by: Optional[str] = None

    class Config:
        arbitrary_types_allowed = True
        json_encoders = {
            datetime: lambda dt: dt.isoformat() if dt else None
        }